package org.eiahe.hr.salary.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.ehe.common.core.utils.MapstructUtils;
import org.ehe.common.core.utils.StringUtils;
import org.ehe.common.mybatis.core.page.PageQuery;
import org.ehe.common.mybatis.core.page.TableDataInfo;
import org.ehe.system.service.ISysDeptService;
import org.eiahe.hr.filler.EmployeeNameFiller;
import org.eiahe.hr.salary.domain.SalaryAdjustmentApplication;
import org.eiahe.hr.salary.domain.SalaryAdjustmentRecord;
import org.eiahe.hr.salary.domain.SalaryStructure;
import org.eiahe.hr.salary.domain.bo.SalaryAdjustmentRecordBo;
import org.eiahe.hr.salary.domain.vo.SalaryAdjustmentRecordVo;
import org.eiahe.hr.salary.mapper.SalaryAdjustmentApplicationMapper;
import org.eiahe.hr.salary.mapper.SalaryAdjustmentRecordMapper;
import org.eiahe.hr.salary.mapper.SalaryStructureMapper;
import org.eiahe.hr.salary.service.ISalaryAdjustmentRecordService;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Collection;
import java.util.Date;
import java.util.List;

/**
 * 调薪记录Service业务层处理
 *
 * @author zhangnn
 */
@RequiredArgsConstructor
@Service
public class SalaryAdjustmentRecordServiceImpl implements ISalaryAdjustmentRecordService {

    private final SalaryAdjustmentRecordMapper baseMapper;
    private final SalaryAdjustmentApplicationMapper applicationMapper;
    private final SalaryStructureMapper salaryStructureMapper;
    private final ISysDeptService deptService;
    private final EmployeeNameFiller employeeNameFiller;

    @Override
    public SalaryAdjustmentRecordVo queryById(Long recordId) {
        SalaryAdjustmentRecordVo salaryAdjustmentRecordVo = baseMapper.selectVoById(recordId);
        employeeNameFiller.fillEmployeeName(salaryAdjustmentRecordVo,
            SalaryAdjustmentRecordVo::getEmployeeNo,
            SalaryAdjustmentRecordVo::setEmployeeName);
        return salaryAdjustmentRecordVo;
    }

    @Override
    public List<SalaryAdjustmentRecordVo> queryList(SalaryAdjustmentRecordBo bo) {
        LambdaQueryWrapper<SalaryAdjustmentRecord> lqw = buildQueryWrapper(bo);
        List<SalaryAdjustmentRecordVo> salaryAdjustmentRecordVos = baseMapper.selectVoList(lqw);
        employeeNameFiller.fillEmployeeNames(salaryAdjustmentRecordVos,
            SalaryAdjustmentRecordVo::getEmployeeNo,
            SalaryAdjustmentRecordVo::setEmployeeName);
        return salaryAdjustmentRecordVos;
    }

    @Override
    public TableDataInfo<SalaryAdjustmentRecordVo> queryPageList(SalaryAdjustmentRecordBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<SalaryAdjustmentRecord> lqw = buildQueryWrapper(bo);
        IPage<SalaryAdjustmentRecordVo> page = baseMapper.selectVoPage(pageQuery.build(), lqw);
        employeeNameFiller.fillEmployeeNames(page.getRecords(),
            SalaryAdjustmentRecordVo::getEmployeeNo,
            SalaryAdjustmentRecordVo::setEmployeeName);
        return TableDataInfo.build(page);
    }

    /**
     * 构建查询条件
     *
     * @param bo 调薪记录业务对象
     * @return 查询条件
     */
    private LambdaQueryWrapper<SalaryAdjustmentRecord> buildQueryWrapper(SalaryAdjustmentRecordBo bo) {
        LambdaQueryWrapper<SalaryAdjustmentRecord> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getEmployeeNo()), SalaryAdjustmentRecord::getEmployeeNo, bo.getEmployeeNo());
        lqw.orderByDesc(SalaryAdjustmentRecord::getCreateTime);
        return lqw;
    }

    @Override
    public Boolean insertByBo(SalaryAdjustmentRecordBo bo) {
        // 自动计算调薪幅度和调薪比例
        calculateAdjustmentFields(bo);

        SalaryAdjustmentRecord add = MapstructUtils.convert(bo, SalaryAdjustmentRecord.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setRecordId(add.getRecordId());
        }
        return flag;
    }

    @Override
    public Boolean updateByBo(SalaryAdjustmentRecordBo bo) {
        // 自动计算调薪幅度和调薪比例
        calculateAdjustmentFields(bo);

        SalaryAdjustmentRecord update = MapstructUtils.convert(bo, SalaryAdjustmentRecord.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 计算调薪幅度和调薪比例
     *
     * @param bo 调薪记录业务对象
     */
    private void calculateAdjustmentFields(SalaryAdjustmentRecordBo bo) {
        // 只有当原薪资和新薪资都不为空时才计算
        if (bo.getOriginalSalary() != null && bo.getNewSalary() != null) {
            // 计算调薪幅度 = 新薪资 - 原薪资
            BigDecimal adjustmentAmount = bo.getNewSalary().subtract(bo.getOriginalSalary());
            bo.setAdjustmentAmount(adjustmentAmount);

            // 计算调薪比例 = (调薪幅度 / 原薪资) * 100%
            if (bo.getOriginalSalary().compareTo(BigDecimal.ZERO) != 0) {
                BigDecimal adjustmentRate = adjustmentAmount
                        .divide(bo.getOriginalSalary(), 4, BigDecimal.ROUND_HALF_UP)
                        .multiply(new BigDecimal(100));
                bo.setAdjustmentRate(adjustmentRate);
            } else {
                bo.setAdjustmentRate(BigDecimal.ZERO);
            }
        }
    }

    /**
     * 保存前的数据校验
     *
     * @param entity 实体类数据
     */
    private void validEntityBeforeSave(SalaryAdjustmentRecord entity) {
        // TODO 做一些数据校验,如唯一约束
    }

    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids) {
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public Boolean createRecordFromApplication(Long applicationId) {
        try {
            // 查询调薪申请
            SalaryAdjustmentApplication application = applicationMapper.selectById(applicationId);
            if (application == null) {
                return false;
            }

            // 检查申请是否已审批通过
            if (!"1".equals(application.getApprovalStatus())) {
                return false;
            }

            // 查询员工是否已有调薪记录
            LambdaQueryWrapper<SalaryAdjustmentRecord> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.eq(SalaryAdjustmentRecord::getEmployeeNo, application.getEmployeeNo());
            queryWrapper.orderByDesc(SalaryAdjustmentRecord::getAdjustmentTime);

            List<SalaryAdjustmentRecord> records = baseMapper.selectList(queryWrapper);
            int adjustmentCount = records.size() + 1;

            // 计算调薪幅度和比例
            BigDecimal adjustmentAmount = application.getNewSalary().subtract(application.getOriginalSalary());
            BigDecimal adjustmentRate = BigDecimal.ZERO;
            if (application.getOriginalSalary().compareTo(BigDecimal.ZERO) != 0) {
                adjustmentRate = adjustmentAmount.divide(application.getOriginalSalary(), 4, BigDecimal.ROUND_HALF_UP)
                        .multiply(new BigDecimal(100));
            }

            // 创建调薪记录
            SalaryAdjustmentRecord record = new SalaryAdjustmentRecord();
            record.setEmployeeNo(application.getEmployeeNo());
            record.setAdjustmentCount(adjustmentCount);
            record.setAdjustmentTime(application.getEffectiveTime());
            record.setAdjustmentAmount(adjustmentAmount);
            record.setAdjustmentRate(adjustmentRate);
            record.setAdjustmentReason(application.getAdjustmentReason());
            record.setOriginalSalary(application.getOriginalSalary());
            record.setNewSalary(application.getNewSalary());

            boolean result = baseMapper.insert(record) > 0;

            // 如果调薪记录创建成功，则自动更新薪资结构表
            if (result) {
                updateSalaryStructure(application, record);
            }

            return result;
        } catch (Exception e) {
            // 记录日志
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 更新薪资结构表
     *
     * @param application 调薪申请
     * @param record      调薪记录
     */
    private void updateSalaryStructure(SalaryAdjustmentApplication application, SalaryAdjustmentRecord record) {
        try {
            // 查询员工最新的薪资结构记录
            LambdaQueryWrapper<SalaryStructure> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.eq(SalaryStructure::getEmployeeNo, application.getEmployeeNo());
            queryWrapper.orderByDesc(SalaryStructure::getYearMonth);

            List<SalaryStructure> structures = salaryStructureMapper.selectList(queryWrapper);
            if (!structures.isEmpty()) {
                SalaryStructure latestStructure = structures.get(0);

                // 创建新的薪资结构记录（基于最新记录）
                SalaryStructure newStructure = new SalaryStructure();
                // 复制基础信息
                newStructure.setTenantId(latestStructure.getTenantId());
                newStructure.setEmployeeNo(latestStructure.getEmployeeNo());
                newStructure.setEmployeeName(latestStructure.getEmployeeName());
                newStructure.setBankCardNo(latestStructure.getBankCardNo());
                newStructure.setBankName(latestStructure.getBankName());
                newStructure.setDepartment(latestStructure.getDepartment());

                // 设置新的年月
                String yearMonth = String.format("%tY%<tm", application.getEffectiveTime());
                newStructure.setYearMonth(yearMonth);

                // 更新基本工资为新的薪资标准
                newStructure.setBaseSalary(record.getNewSalary());

                // 保持其他字段不变
                newStructure.setJobLevelSalary(latestStructure.getJobLevelSalary());
                newStructure.setPositionSalary(latestStructure.getPositionSalary());
                newStructure.setPerformanceSalary(latestStructure.getPerformanceSalary());
                newStructure.setDutyAllowance(latestStructure.getDutyAllowance());
                newStructure.setShouldAttendanceDays(latestStructure.getShouldAttendanceDays());
                newStructure.setAbsenceDays(latestStructure.getAbsenceDays());
                newStructure.setPaidAttendanceDays(latestStructure.getPaidAttendanceDays());
                newStructure.setAbsenceDeduction(latestStructure.getAbsenceDeduction());
                newStructure.setMealAllowance(latestStructure.getMealAllowance());
                newStructure.setOtherAdjustment(latestStructure.getOtherAdjustment());
                newStructure.setMealDeduction(latestStructure.getMealDeduction());
                newStructure.setGrossSalary(latestStructure.getGrossSalary());
                newStructure.setPensionDeduction(latestStructure.getPensionDeduction());
                newStructure.setUnemploymentDeduction(latestStructure.getUnemploymentDeduction());
                newStructure.setMedicalDeduction(latestStructure.getMedicalDeduction());
                newStructure.setMajorMedicalDeduction(latestStructure.getMajorMedicalDeduction());
                newStructure.setSocialInsurancePersonal(latestStructure.getSocialInsurancePersonal());
                newStructure.setHousingFundPersonal(latestStructure.getHousingFundPersonal());
                newStructure.setSocialHousingTotal(latestStructure.getSocialHousingTotal());
                newStructure.setTaxableSalary(latestStructure.getTaxableSalary());
                newStructure.setPersonalTax(latestStructure.getPersonalTax());
                newStructure.setNetSalary(latestStructure.getNetSalary());
                newStructure.setStatus(latestStructure.getStatus());

                // 插入新的薪资结构记录
                salaryStructureMapper.insert(newStructure);
            }
        } catch (Exception e) {
            // 记录日志
            e.printStackTrace();
        }
    }
}
